package com.education.platform.api.controller.user;

import com.alibaba.fastjson.JSON;
import com.alipay.api.internal.util.AlipaySignature;
import com.education.platform.api.pay.alipay.AliPayService;
import com.education.platform.api.pay.wxpay.WxService;
import com.education.platform.api.service.PayRecordService;
import com.education.platform.api.vo.request.PayRecordUpdateVO;
import com.education.platform.api.vo.response.AliPayResponseVO;
import com.education.platform.common.enums.PaymentTypeEnum;
import com.education.platform.common.exception.BusinessException;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import static com.alipay.api.AlipayConstants.CHARSET_UTF8;
import static com.education.platform.api.pay.alipay.AlipayConfig.ALIPAY_PUBLIC_KEY;
import static com.education.platform.api.pay.alipay.AlipayConfig.SIGN_TYPE;

/**
* describe: 支付
* @author : tomato
* @date: 2020-06-06 02:55:51.638
**/
@RestController
@Api("微信/支付宝 支付")
@RequestMapping("pay")
@Validated
public class PayController {

    private static final Logger LOGGER = LoggerFactory.getLogger(PayController.class);

	@Autowired
    private AliPayService aliPayService;
    @Autowired
    private WxService wxService;

	@Autowired
     private PayRecordService payRecordService;



    /**
     * 创建支付订单-支付宝支付
     * @param
     * @return
     */
    @ApiOperation(value = "创建支付订单-支付宝支付")
    @PostMapping("aliPayRequest")
    public AliPayResponseVO aliPayRequest(@RequestBody @Valid PayRecordUpdateVO request){
        LOGGER.info("创建支付宝订单："+ JSON.toJSONString(request));
        request.setPaymentPlatformType(PaymentTypeEnum.ALI_PAY.getValue());
        String orderNo = payRecordService.savePayRecord(request);
        request.setOrderNo(orderNo);
        String param =   aliPayService.payRequest(request);
        AliPayResponseVO responseVO = new AliPayResponseVO();
        responseVO.setParamStr(param);
        return responseVO;
    }



    /**
     * 支付宝充值后回调地址
     * @param
     * @return
     */
    @ApiOperation(value = "支付宝支付成功后回调地址",hidden = true)
    @RequestMapping(value = "aliCallBack",method = {RequestMethod.POST,RequestMethod.GET})
    public void aliCallBack(HttpServletRequest request, HttpServletResponse httpServletResponse){
        LOGGER.info("收到支付宝回调>>>>>>>>>>>>");
        //获取post参数转为map
        Map<String, String> map = aliPayService.getParamFormRequest(request);
        LOGGER.info("支付宝回调参数："+JSON.toJSONString(map));
        if(map==null||map.isEmpty()){
            throw new BusinessException("参数校验失败");
        }
        //校验是否是支付宝发出的信息
        try {
            Boolean result =  AlipaySignature.rsaCheckV1(map, ALIPAY_PUBLIC_KEY, CHARSET_UTF8, SIGN_TYPE);
            LOGGER.info("支付宝回调验签结果：result=>>>"+result);
            //验证成功
        if (result) {
            //商户订单号
            String outTradeNo = map.get("out_trade_no");
            //支付宝交易号
            String tradeNo = map.get("trade_no");
            //交易状态
            String tradeStatus = map.get("trade_status");
            LOGGER.info("trade_status==" + tradeStatus);
            LOGGER.info("outTradeNo==" + outTradeNo);
            LOGGER.info("tradeNo==" + tradeNo);
            if("TRADE_SUCCESS".equals(tradeStatus)) {
                LOGGER.info("收到支付宝回调状态：TRADE_SUCCESS");
                    payRecordService.paySuccess(outTradeNo,tradeNo);
                    httpServletResponse.getWriter().print("success");

            }

        } else {//验证失败
            LOGGER.error("回调接口验证失败");
            httpServletResponse.getWriter().print("fail");
        }
        }catch (Exception e){
            LOGGER.error("回调接口验证失败");
        }
        LOGGER.info("支付宝回调参数："+JSON.toJSONString(map));
    }


    /**
     * 创建支付订单-微信支付
     * @param
     * @return
     */
    @ApiOperation(value = "创建支付订单-微信支付")
    @PostMapping("wxPayRequest")
    public Map<String,String> wxPayRequest(@RequestBody @Valid PayRecordUpdateVO request){
        request.setPaymentPlatformType(PaymentTypeEnum.WX_PAY.getValue());
        String orderNo = payRecordService.savePayRecord(request);
        request.setOrderNo(orderNo);
        try {
            Map<String,String> prepayMap =  wxService.wxPay(request);
            LOGGER.info("app微信预支付参数："+prepayMap);
            return prepayMap;
        }catch (Exception e){
          LOGGER.error("创建微信支付失败："+e.getMessage());
        }
      throw new BusinessException("创建微信支付失败");
    }

/**
 *   微信支付异步结果通知
 *   https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3
 */
    @ApiOperation(value = "微信支付成功后回调地址",hidden = true)
    @RequestMapping(value = "wxCallBack",method = {RequestMethod.POST,RequestMethod.GET})
    public String wxCallBack(HttpServletRequest request, HttpServletResponse response) {
        LOGGER.info("收到微信回调：");
        String resXml = "";
        Map<String,String> resultMap = new HashMap<>(2);
        try {
            InputStream inputStream = request.getInputStream();
            //将InputStream转换成xmlString
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder sb = new StringBuilder();
            String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            resXml = sb.toString();
            resultMap = wxService.payBack(resXml);
        } catch (Exception e) {
            LOGGER.error("微信支付失败:" + e.getMessage());
            resultMap.put("return_code", WXPayConstants.FAIL);
            resultMap.put("return_msg","回调数据异常");
        }
        try {
            return WXPayUtil.mapToXml(resultMap);
        }catch (Exception e){
            LOGGER.error("mapToXml失败："+e.getMessage());
        }
       return  "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[失败]]></return_msg>" + "</xml> ";
    }



}
